package com.hmjk.health.background.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.text.format.Time;
import android.util.Log;

import com.hmjk.health.HealthApp;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.background.DatabaseHelper;
import com.hmjk.health.background.NetService;
import com.hmjk.health.util.DEV_DATA;

public class DeviceSubListUpdate extends DataUpdated{
	private static String TAG = DeviceSubListUpdate.class.getSimpleName();
	private ArrayList<String> mTIDArray = new ArrayList<String>();
	private int index = 0;
	private boolean working = false;
	//private boolean doSingle = false;
	
	private void logd(String info){
		Log.d(TAG, info);
	}
	
	public DeviceSubListUpdate(HealthApp app, DataManager dm, DataUpdated base) {
		super(app, dm, base);
		UPDATE_TIME = 60 * 60 * 1000;
		mBaseData.setNotifer(DataManager.F_DEVICESUBLIST, this);
	}

	@Override
	public void setUserData(Object data) {
		logd("setUserData");
		reqTime = 0;
		upTime = 0;
		
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(dh == null)
			return;
		
		HashMap<String,String> checkmap = new HashMap<String,String>();
		for(String tid:mTIDArray){
			checkmap.put(tid, tid);
		}
		
		getTids();
		for(String tid:mTIDArray){
			checkmap.remove(tid);
		}
		
		
		Iterator<Entry<String, String>> iter = checkmap.entrySet().iterator();
		while(iter.hasNext()){
			Entry<String,String> entry = (Entry<String,String>) iter.next();
			String tid = entry.getValue();
			Cursor c = dh.queryDevsublistTableData(tid);
			
			if(c.getCount() > 0){
				c.moveToFirst();
				String table = c.getString(c.getColumnIndex(DatabaseHelper.DEVSUBLIST_TABLE));
				if((table != null) && (table.trim().length() > 0)){
					if(dh.isTableExists(table)){
						dh.deleteTable(table);
					}
				}
				dh.deleteOneItemInDevsublistTable(tid);
			}
			c.close();
		}
	}

	@Override
	public long delay() {
		long curMs = System.currentTimeMillis();
		long del = curMs - upTime;
		logd("delay curMs="+curMs+" upTime="+upTime+" del="+del);
		if(del >= UPDATE_TIME){
			logd("delay 0");
			return 0;
		}else{
			logd("delay (UPDATE_TIME - del) = "+(UPDATE_TIME - del));
			return (UPDATE_TIME - del);
		}
	}

	private void getTids(){
		JSONObject json = (JSONObject) mBaseData.check(null);
	
		mTIDArray.clear();
		index = 0;
		if(json != null){
			try {
				JSONArray ar = json.getJSONArray("array");
				int len = ar.length();
				for(int i = 0; i < len; i++){
					JSONObject e = ar.getJSONObject(i);
					String tid = e.getString("tid");
					String type = e.getString("type");
					String name = e.getString("name");
					logd("device, tid=" + tid + ", type=" + type);
					
					if(DEV_DATA.isHealthDev(type)){
						mTIDArray.add(tid);
					}
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
	}
	
	private boolean hasNext(){
		int size = mTIDArray.size();
		if(index < (size - 1))
			return true;
		else
			return false;
	}
	
	private void doNextRequest(){
		int size = mTIDArray.size();
		if(size > 0){
			index ++;
			if(index < size){
				doRequest();
			}else {
				working = false;
			}
		}else {
			working = false;
		}
	}
	
	private void doRequest(){
		int size = mTIDArray.size();
		logd("doRequest:size="+size);
		
		if(size > 0){
			String tid = mTIDArray.get(index);
			Intent si = new Intent(NetService.GET_DATA_ACTION);
			si.putExtra("sub_act", NetService.GET_DEVICE_SUB_LIST);
			si.putExtra("tid", tid);
			
			Time t = new Time();
			t.setToNow();
			String stamp = "GET_DEVICE_SUB_LIST" + t.toString();
			si.putExtra("stamp",stamp);
			mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
			mApp.startService(si);
	
		}else {
			working = false;
			Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
			i.putExtra("type",DataManager.F_DEVICESUBLIST);
			i.putExtra("state", false);
			i.putExtra("tid", "");
			mApp.sendBroadcast(i);
		}
	}
	
	@Override
	public boolean grab() {
		if(working){
			logd("grab working now");
			return false;
		}
		
		getTids();
		if (mTIDArray.isEmpty()) {
			logd("grab mTIDArray is empty");
			return false;
		}
		
		long curMs = System.currentTimeMillis();
		logd("grab curMs="+curMs+" reqTime="+reqTime);
		
		if((curMs - reqTime) > UPDATE_TIME){
			working = true;
			doRequest();
			reqTime = curMs;
			logd("grab req sent!");
			return true;
		}
		
		return false;
	}

	@Override
	public boolean grabByUser() {
		if(working){
			logd("grabByUser working now");
			return false;
		}
		
		getTids();
		if (mTIDArray.isEmpty()) {
			return false;
		}
		
		long curMs = System.currentTimeMillis();
		logd("grabByUser curMs="+curMs+" reqTime="+reqTime);
		
		if((curMs - reqTime) > MIN_QUERY_DUR * 1000){
			working = true;
			doRequest();
			reqTime = curMs;
			logd("grabByUser req sent!");
			return true;
		}
		
		return false;
	}
	
	@Override
	public boolean grabByUserWithSingleArgs(Object args){
		return false;
	}
	
	@Override
	public void receive(String stamp, String sjson) {
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(dh == null)
			return;
		
		if(stamp.startsWith("GET_DEVICE_SUB_LIST")){
			if(sjson != null){
				boolean update = false;
				String tid = "";
				try {
					JSONObject json = new JSONObject(sjson);
					int code = json.getInt("code");
					if(code == 200){
						String state = json.getString("state");
						if(state.equalsIgnoreCase("00")){
							JSONObject sd = json.getJSONObject("senddata");
							JSONObject recdata = json.getJSONObject("recdata");
							if(recdata != null){
								JSONArray array = null;
								tid = sd.getString("tid");
								Cursor c = dh.queryDevsublistTableData(tid);
							
								String table = null;
								if(c.getCount() > 0){
									c.moveToFirst();
									table = c.getString(c.getColumnIndex(DatabaseHelper.DEVSUBLIST_TABLE));
								}
								c.close();
								
								upTime = System.currentTimeMillis();
								
								update = true;
								
								if(recdata.has("subcodearr")){
									array = recdata.getJSONArray("subcodearr");
								}
								
								if((array != null) && (array.length() > 0)){
									ContentValues cv = new ContentValues();
									cv.put(DatabaseHelper.DEVSUBLIST_TID, tid);
									cv.put(DatabaseHelper.DEVSUBLIST_TIME, upTime);
									
									if((table == null) || table.trim().isEmpty()){
										table = dh.createDevSubInfoTable(tid, cv);
									}
									
									for(int i= 0; i < array.length(); i ++){
										String subcode = array.getString(i);
										dh.addOneInDevSubInfoTable(table, tid, subcode, upTime);
									}
									dh.deleteItemsInDevSubInfoListBeforeGivenTime(table, upTime);
									if(hasNext() ==  false){
										DataUpdated mNotifer = getNotifier(DataManager.F_DEVICESUBINFO);
										if(mNotifer != null)
											mNotifer.setUserData(null);
									}
								}else{
									if((table != null) && (table.trim().length() > 0)){
										dh.deleteTable(table);
										table = "";
									}
									ContentValues cv = new ContentValues();
									cv.put(DatabaseHelper.DEVSUBLIST_TID, tid);
									cv.put(DatabaseHelper.DEVSUBLIST_TABLE, table);
									cv.put(DatabaseHelper.DEVSUBLIST_TIME, upTime);
									dh.updateOneItemInDevsublistTable(tid, cv);
									if(hasNext() ==  false){
										DataUpdated mNotifer = getNotifier(DataManager.F_DEVICESUBINFO);
										if(mNotifer != null)
											mNotifer.setUserData(null);
									}
								}
								dh.closeDB();
							}
						}
					}
					
				} catch (JSONException e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				doNextRequest();
				Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
				i.putExtra("type",DataManager.F_DEVICESUBLIST);
				i.putExtra("state", update);
				i.putExtra("tid", tid);
				mApp.sendBroadcast(i);
			}
		}
		
	}

	@Override
	public Object check(String[] arg) {
		JSONObject ret = null;
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(dh == null)
			return null;
		
		if(arg == null){
			//return all
			Cursor c = dh.queryDevsublistTableData();
			try {
				ret = new JSONObject();
				if(c.getCount() > 0){
					JSONArray array = new JSONArray();
					while(c.moveToNext()){
						String tid = c.getString(c.getColumnIndex(DatabaseHelper.DEVSUBLIST_TID));
						String table = c.getString(c.getColumnIndex(DatabaseHelper.DEVSUBLIST_TABLE));	
						
						JSONObject e = new JSONObject();
						e.put("tid", tid);
						e.put("table", table);
						array.put(e);
					}
					ret.put("array", array);
					ret.put("uptime", upTime);
				}else {
					JSONArray array = new JSONArray();
					ret.put("array", array);
					ret.put("uptime", upTime);
				}
			} catch (JSONException e1) {
				// TODO: handle exception
				e1.printStackTrace();
				ret = null;
			}
			c.close();
			dh.closeDB();
		}else if(arg[0] != null){
			String tid = arg[0];
			Cursor c = dh.queryDevsublistTableData(tid);
			try {
				ret = new JSONObject();
				if(c.getCount() > 0){
					c.moveToFirst();
					
					String table = c.getString(c.getColumnIndex(DatabaseHelper.DEVSUBLIST_TABLE));	
					ret.put("tid", tid);
					ret.put("table", table);
				}
			} catch (JSONException e1) {
				// TODO: handle exception
				e1.printStackTrace();
				ret = null;
			}
			if(c != null)
				c.close();
			dh.closeDB();
		}
		return ret;
	}

	@Override
	public boolean commit(Object data) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void release() {
		// TODO Auto-generated method stub
		
	}

}
